﻿using Mapster;
using Microsoft.AspNetCore.Http;
using Nest;
using SqlSugar;
using System.Diagnostics;
using System.Web;

namespace Magic.System;
/// <summary>
/// 管理员服务类
/// </summary>
[Injection]
public class SysUserService : ISysUserService
{
    private readonly HttpContext _httpContext;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="httpContextAccessor"></param>
    public SysUserService(IHttpContextAccessor httpContextAccessor)
    {
        _httpContext = httpContextAccessor.HttpContext;
    }
    /// <summary>
    /// 分页返回管理员
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<SugarPagedList<SysUserPageItem>> GetPageList(BasePageInput page, SysUserPageInput input)
    {
        var pageList = await SugarContext.Instance.Queryable<SysUser>()
            .WhereIF(!string.IsNullOrEmpty(input.quick_search), p => p.Username.Contains(input.quick_search) || p.Nickname.Contains(input.quick_search))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Username), m => m.Username.Contains(input.Username))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Nickname), m => m.Username.Contains(input.Nickname))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Username), m => m.Mobile.Contains(input.Mobile))
            .WhereIF(!string.IsNullOrWhiteSpace(input.Email), m => m.Mobile.Contains(input.Email))
            .WhereIF(!input.LastLoginTime.IsNull() && input.LastLoginTime.Start > 0, m => m.Lastlogintime >= input.LastLoginTime.Start)
            .WhereIF(!input.LastLoginTime.IsNull() && input.LastLoginTime.End > 0, m => m.Lastlogintime <= input.LastLoginTime.End)
            .WhereIF(!input.CreateTime.IsNull() && input.CreateTime.Start > 0, m => m.Createtime >= input.CreateTime.Start)
            .WhereIF(!input.CreateTime.IsNull() && input.CreateTime.End > 0, m => m.Createtime <= input.CreateTime.End)
            .Select(m => new SysUserPageItem { }, true)
            .ToPagedListAsync(page.Page, page.Limit);

        //获取用户角色关系
        var adminGroupAccessList = await SugarContext.Instance.Queryable<SysUserRole>()
            .Where(m => pageList.List.Select(it => it.Id).Contains(m.Uid))
            .Includes(m => m.SysRole)
            .ToListAsync();
        pageList.List.ForEach(m =>
        {
            m.group_arr = adminGroupAccessList.Where(it => it.Uid == m.Id).Select(it => it.RoleId).ToArray();
            m.group_name_arr = adminGroupAccessList.Where(it => it.Uid == m.Id).Select(it => it.SysRole.Name).ToArray();
            m.Avatar = ConvertAvatar(m.Avatar);
        });
        return pageList;
    }

    /// <summary>
    /// 根据id返回Admin
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task<SysUserDetailOutput> Get(int id)
    {
        var admin = await SugarContext.Instance.Queryable<SysUser>()
            .Where(p => p.Id == id)
            .Includes(p => p.AdminGroupAccesses)
            .FirstAsync();
        _ = admin ?? throw new ApiException("当前查询无数据");
        var adminOutput = admin.Adapt<SysUserDetailOutput>();
        adminOutput.group_arr = admin.AdminGroupAccesses.Select(m => m.RoleId).ToArray();
        adminOutput.group_name_arr = await SugarContext.Instance.Queryable<SysRole>()
            .Where(p => adminOutput.group_arr.Contains(p.Id))
            .Select(p => p.Name)
            .ToArrayAsync();
        adminOutput.Avatar = ConvertAvatar(adminOutput.Avatar);
        return adminOutput;
    }
    /// <summary>
    /// 新增Admin管理员
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task Add(AddSysUserInput input)
    {
        //校验用户名是否存在
        var adminUserName = await SugarContext.Instance.Queryable<SysUser>()
            .Where(p => p.Username == input.Username)
            .AnyAsync();
        if (adminUserName)
            throw new ApiException($"[{input.Username}]用户名已存在");
        //校验手机号是否已存在
        var adminMobile = await SugarContext.Instance.Queryable<SysUser>()
            .Where(p => p.Mobile == input.Mobile)
            .AnyAsync();
        if (adminMobile)
            throw new ApiException($"[{input.Mobile}]手机号已存在");
        try
        {
            var admin = input.Adapt<SysUser>();
            var encryPassword = MD5Encryption.Encrypt(input.Password);
            admin.Password = encryPassword;
            //新增Admin
            var adminId = await SugarContext.Instance.Insertable<SysUser>(admin).ExecuteReturnIdentityAsync();
            var group_arrs = new List<SysUserRole>();
            for (int i = 0; i < input.group_arr.Length; i++)
            {
                group_arrs.Add(new SysUserRole
                {
                    Uid = adminId,
                    RoleId = Convert.ToInt32(input.group_arr[i])
                });
            }
            //权限分组
            await SugarContext.Instance.Insertable<SysUserRole>(group_arrs).ExecuteCommandAsync();
        }
        catch (Exception ex)
        {
            throw new ApiException(ex.Message);
        }
    }
    /// <summary>
    /// 删除Admin
    /// </summary>
    /// <param name="ids">id集合</param>
    /// <returns></returns>
    public async Task Delete(List<int> ids)
    {
        if (ids.Count == 0)
            throw new ApiException("参数不能为空");
        //获取待删除分组集合
        var admin = await SugarContext.Instance.Queryable<SysUser>()
            .Where(p => ids.Contains(p.Id))
            .ToListAsync();
        //判断删除数据与传入数据总数是否一致
        if (ids.Count != admin.Count)
            throw new ApiException("传入数据与操作数据不一致,请刷新再试");
        try
        {
            //删除权限分组
            await SugarContext.Instance.Deleteable<SysUserRole>().Where(p => ids.Contains(p.Uid)).ExecuteCommandAsync();

            //删除Admin
            await SugarContext.Instance.Deleteable<SysUser>()
             .Where(p => ids.Contains(p.Id))
             .ExecuteCommandAsync();
        }
        catch (Exception ex)
        {
            throw new ApiException(ex.Message);
        }
    }
    /// <summary>
    /// 编辑Admin
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task Edit(EditSysUserInput input)
    {
        var admin = await SugarContext.Instance.Queryable<SysUser>().FirstAsync(p => p.Id == input.id);
        _ = admin ?? throw new ApiException("当前查询无数据");

        //校验用户名是否存在
        var adminUserName = await SugarContext.Instance.Queryable<SysUser>().Where(p => p.Username == input.Username && p.Id != input.id).AnyAsync();
        if (adminUserName)
            throw new ApiException($"[{input.Username}]用户名已存在");
        //校验手机号是否已存在
        var adminMobile = await SugarContext.Instance.Queryable<SysUser>().Where(p => p.Mobile == input.Mobile && p.Id != input.id).AnyAsync();
        if (adminMobile)
            throw new ApiException($"[{input.Mobile}]手机号已存在");

        if (!string.IsNullOrWhiteSpace(input.Password))
            input.Password = MD5Encryption.Encrypt(input.Password);
        else
            input.Password = admin.Password;
        {
            input.Password= MD5Encryption.Encrypt(input.Password);
        }
        else
        {
            input.Password = admin.Password;
        }

        input.Adapt(admin);
        //删除角色分组
        await SugarContext.Instance.Deleteable<SysUserRole>().Where(p => p.Uid == input.id).ExecuteCommandAsync();
        //重新插入分组
        var group_arrs = new List<SysUserRole>();
        for (int i = 0; i < input.group_arr.Length; i++)
        {
            group_arrs.Add(new SysUserRole
            {
                Uid = input.id,
                RoleId = Convert.ToInt32(input.group_arr[i])
            });
        }
        //权限分组
        await SugarContext.Instance.Insertable<SysUserRole>(group_arrs).ExecuteCommandAsync();
        //编辑用户
        await SugarContext.Instance.Updateable<SysUser>(admin).ExecuteCommandAsync();
    }

    private string ConvertAvatar(string avatar)
    {
        var serveUrl = $"{_httpContext.Request.Scheme}://{_httpContext.Request.Host}/";//服务地址

        avatar = string.IsNullOrEmpty(avatar) ? "https://foruda.gitee.com/avatar/1676956773129799330/1210212_zhengguojing_1651132211.png3333" : avatar?.Contains("http") ?? false ? avatar : string.Concat(serveUrl, avatar);

        return avatar;
    }
}
